package io.gitee.zhangbinhub.acp.cloud.server.helloworld;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudAtomApplication;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * @since JDK 17
 */
@AcpCloudAtomApplication
public class HelloWorldReactiveApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(HelloWorldReactiveApplication.class);
        app.setWebApplicationType(WebApplicationType.REACTIVE);
        app.run(args);
    }

    @Bean("customerWebClientTest")
    @LoadBalanced
    public WebClient.Builder webClient(FeignHttpClientProperties feignHttpClientProperties, ObjectMapper objectMapper) {
        return WebClient.builder()
                .clientConnector(
                        new ReactorClientHttpConnector(
                                HttpClient.create().option(
                                                ChannelOption.CONNECT_TIMEOUT_MILLIS,
                                                (int) Duration.of(
                                                        feignHttpClientProperties.getHc5().getConnectionRequestTimeout(),
                                                        feignHttpClientProperties.getHc5().getConnectionRequestTimeoutUnit().toChronoUnit()
                                                ).toMillis()
                                        )
                                        .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(feignHttpClientProperties.getConnectionTimeout(), TimeUnit.MILLISECONDS)))
                        )
                ).codecs(configuration -> {
                    configuration.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON));
                    configuration.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON));
                });
    }
}
